﻿package fwk.utiles
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.geom.ColorTransform;
	import flash.display.MovieClip;
	import flash.display.FrameLabel;
	import flash.events.MouseEvent;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.text.TextField;
	import flash.text.TextLineMetrics;
	
	import fwk.loaderManager.LoadSingleElement;
	
	import flash.utils.getDefinitionByName;
	
	public class Utiles extends MovieClip
	{
		private var _loader:LoadSingleElement;
		private var _container:DisplayObjectContainer;
		private var _onCompleteFunc:Function;
		private var _onError:Function;
		private var _params:Array;
		
		
		
		
		//-----------------------------------------------------------------------
		function Utiles()
		{
			
		}
		
		//----------------------------------------------------------
		//---- Efface tous les enfants du clip
		//----------------------------------------------------------
		public static function removeAllChild(clip:Object):void {			
			if(clip != null && clip is DisplayObjectContainer){
				var i:uint = 0;
				var nb:uint = clip.numChildren;
				var obj:DisplayObject;
				
				var tabToDelete:Array = new Array();

				for (i = 0; i < nb; i++)
				{
					obj = clip.getChildAt(i);
					tabToDelete.push(obj);
				}
				// delete clip
				nb = tabToDelete.length;
				for (i = 0; i < nb; i++) {
					obj = tabToDelete[i];
					clip.removeChild(obj);
				}
			}
		}
		//----------------------------------------------------------
		//---- Efface tous les enfants du clip ainsi que le clip container
		//----------------------------------------------------------
		public static function removeObjectContainer(clip:Object):void{
			if(clip != null && clip is DisplayObjectContainer){
				removeAllChild(clip);
				//trace("delete clip : " + clip);
				clip.parent.removeChild(clip);
			}
			
		}
		//----------------------------------------------------------
		//---- Etats bouton
		//----------------------------------------------------------
		public static function initRollOver(clip:Object):void {
			clip.buttonMode = true;
			clip.mouseChildren = false;
			clip.addEventListener(MouseEvent.ROLL_OVER, n_onRollOver);
			clip.addEventListener(MouseEvent.ROLL_OUT, n_onRollOut);
		}
		//--------------------------------------------------------
		public static function initButFondSize(clip:MovieClip):void {
			
			clip.fond.f.width = clip.texte.width + (clip.texte.x - clip.fond.g.width)*2 + 2;
			clip.fond.d.x = clip.fond.f.x + clip.fond.f.width + clip.fond.d.width;
		}
		
		private static function n_onRollOver(evt:MouseEvent):void{
			(evt.currentTarget as Object).gotoAndPlay("over");
			//(evt.currentTarget as Object).gotoAndPlay("on");
		}
		//----------------------------------------------------------
		private static function n_onRollOut(evt:MouseEvent):void{
			(evt.currentTarget as Object).gotoAndPlay("out");
			//(evt.currentTarget as Object).gotoAndPlay("off");
		}
		
		
		//----------------------------------------------------------
		//---- Renvoi true si le lbal existe dans le clip
		//----------------------------------------------------------
		public static function labelExist(labelNameToTest:String, clip:MovieClip):Boolean
		{
			var flag:Boolean = false;
			for (var i:int = 0; i < clip.currentLabels.length; i++) {
				var label:FrameLabel = clip.currentLabels[i];
				if (labelNameToTest == label.name) {
					flag = true;
					break;
				}
			}
			
			return flag;
		}
		//----------------------------------------------------------
		//---- applique un degrade sur un champ texte
		//----------------------------------------------------------
		public static function setDegradeTexte(clipDegrade:MovieClip, tTexte:TextField):void
		{
			var textBox:Rectangle = tTexte.getCharBoundaries(0);
			
			if(tTexte.text.length > 0 && textBox != null){
				var container:DisplayObjectContainer = tTexte.parent as DisplayObjectContainer;
				
				if (container.getChildByName("____degradeTexte") == null) {
					clipDegrade.name = "____degradeTexte";
					container.addChild(clipDegrade);
				}else {
					clipDegrade = container.getChildByName("____degradeTexte") as MovieClip;
				}

				clipDegrade.mask = tTexte;
				clipDegrade.x =  tTexte.x + textBox.x;
				clipDegrade.y =  tTexte.y + textBox.y;
				trace("Rectangle text x " + textBox.x);
				trace("Rectangle text y " + textBox.y);
				clipDegrade.width = tTexte.width ;
				clipDegrade.height = tTexte.textHeight;
			}
		}
		
		//----------------------------------------------------------
		//---- charge un element dans container
		//----------------------------------------------------------
		//----------------------------------------------------------------
		public static function loadElement(url:String, container:DisplayObjectContainer, onComplete:Function = null, params:Array = null, onError:Function = null ):void
		{

			var ut:Utiles = new Utiles();
			ut._loadElement(url, container, onComplete, params, onError);
						

		}
		public function _loadElement(url:String, container:DisplayObjectContainer, onComplete:Function = null, params:Array = null, onError:Function = null ):void
		{
			trace("_loadElement " + url + " in " + container);
			
			_onCompleteFunc = onComplete;
			_onError 		= onError;
			_params 		= params;
			_container 		= container;
			
			
			_loader = new LoadSingleElement();
			_loader.addEventListener("elementLoaded", this.funcCompleteElement);
			_loader.addEventListener("IO_ERROR", this.funcErrorElement);
			_loader.loade(container, url);
			
		}
		private function funcCompleteElement(evt:Event):void
		{
			trace("funcCompleteLElement " + _loader.theContent);
			
			if (_loader.theContent is Bitmap) {
				(_loader.theContent as Bitmap).smoothing = true;
			}
			_container.addChild(_loader.theContent as DisplayObject);
			
			if (_onCompleteFunc != null) {
				if (_params != null) _onCompleteFunc(_params);
				else _onCompleteFunc();
			}
		}
		private function funcErrorElement(evt:Event):void
		{
			trace("XXX funcErrorElement");
			if (_onError != null) {
				_onError();
			}

		}
		/**
		 * getObjectFromLibrary
		 * @param	id
		 * @return
		 */
		public static function getObjectFromLibrary(id:String):Object
		{
			var cl:Class = getDefinitionByName(id) as Class;
			var obj:Object = new cl();
			
			return obj;
		}
		
		/**
		 * 
		 * change les valeurs des propriétés des MovieClips passés en paramètres
		 * 
		 * @param	aMovieClips
		 * @param	aProperties
		 * @param	aValues
		 * @return
		 * 
		 * @example Le code suivant change les valeurs des propriétés des MovieClips passés en paramètres
		 *
		 * changeProperty([mcCar1, mcCar2], ["alpha", "visible"], [false, 0]);
		 * 
		 */
		
		public static function changeProperty(aMovieClips:Array, aProperties:Array, aValues:Array):void
		{
			var nMovieClipsArrayLength:uint = aMovieClips.length;
			var nPropertiesArrayLength:uint = aProperties.length;
			var nValuesArrayLength:uint = aValues.length;
			
			for (var i:uint = 0; i < nMovieClipsArrayLength; i++)
			{
				for (var j:uint = 0; j < nPropertiesArrayLength; j++)
				{
					aMovieClips[i][aProperties[j]] = aValues[i];
					trace("site : changeProperty > " + aMovieClips[i].name + "." + aProperties[j] + " = " + aMovieClips[i][aProperties[j]] + ")");
				}
			}
		}
		
		/**
		 * 
		 * dans un tableau d'objet, retourne une propriété à partir de la valeur d'une autre propriété
		 * 
		 * @param	a
		 * @param	sProp
		 * @param	oValue
		 * @return	un tableau à partir du filtre d'un tableau avec la valeur d'une propriété
		 * 
		 * @example Le code suivant retourne un tableau de voitures dont la vitesse maximale est 190
		 *
		 * var aCars190	:Array = filterObjectsArray(aCars, "speedMax", 190);
		 * 
		 */
		
		public static function filterObjectsArray(a:Array, sProp:String, oValue:Object):Array
		{
			var aNewValues:Array = new Array();
			
			for (var i:int = 0; i < a.length; i++) 
			{
				if (a[i][sProp] == oValue)
				{
					aNewValues.push(a[i]);
				}
			}
			
			return aNewValues;
		}
		
		/**
		 * 
		 * dans un tableau d'objet, retourne une propriété à partir de la valeur d'une autre propriété
		 * 
		 * @param	a
		 * @param	sProp1
		 * @param	sProp2
		 * @param	oValue
		 * @return	une propriété à partir de la valeur d'une autre propriété
		 * 
		 * @example Le code suivant retourne la vitesse maximale d'une voiture à partir de son modèle
		 *
		 * var nSpeedMax	:int = findThisPropWithThatProp(aCars, "speedMax", "modèle", "opel_vectra");
		 * 
		 */
		public static function findThisPropWithThatProp(a:Array, sProp1:String, sProp2:String, oValue:Object):Object
		{
			var nArrayLength:Number = a.length;
			var returnValue:Object;
			
			for(var i:Number=0; i<nArrayLength; i++)
			{
				if(a[i][sProp2] == oValue)
				{
					returnValue = a[i][sProp1];
					break;
				}
				else
				{
					returnValue = null;
				}
			}
			
			return returnValue;
		}
		
		/**
		 * 
		 * arrondit un nombre flottant à un certain nombre de chiffre après la virgule
		 * 
		 * @param	nNumber
		 * @param	nDec
		 * @return	un nombre arrondi à un certain nombre de chiffres après la virgule
		 * 
		 * @example Le code suivant retourne un nombre arrondi (13.439)
		 *
		 * var nRating		:Number = 13.438716781;
		 * var nRatingNew	:Number = roundAfterComma(nRating, 3);
		 * 
		 */
		public static function roundAfterComma(nNumber:Number, nDec:Number):String
		{

			// sets decimal places to two by multiplying what's inside the
			// math.round function by 100, and then dividing by 100
			var nMultiple:Number = Math.pow(10, nDec);
			var sNumber:String = String(Math.round(nNumber*(nMultiple))/nMultiple);

			//if the result is infinity or in exponential form,
			//skip the comma code
			if (sNumber.indexOf('e') != (-1)||sNumber.indexOf('Infinity')!=(-1))
			{
			}
			else
			{
				//adds zero if one number after decimal
				var nCommaIndex:Number = sNumber.indexOf('.');
				var nNbNumbersAfterComma:Number = sNumber.length-nCommaIndex;
				
				var i:Number;
				
				if(nNbNumbersAfterComma < nDec)
				{
					for (i=0; i<nNbNumbersAfterComma; i++)
					{
						sNumber += '0';
					}
				}
				//adds two zeroes if no decimal places
				if (sNumber.indexOf('.') == -1)
				{
					sNumber += '.';
					for (i=0; i<nDec; i++)
					{
						sNumber += '0';
					}
				}
				//fixes a bug that occurs if you have a negative sign in a place
				//that would otherwise get a comma after it
				if (sNumber.charAt(0) == "-" && sNumber.charAt(1) == ",")
				{
					sNumber = '-' + sNumber.slice(2);
				}
			}
			//returns result with dollar sign in front
			return sNumber;
		}
		/**
		 * Desactive les tabIndex sur le clip
		 * @param	clip sur lequel on veut desactiver tous les tabIndex (prend en compte les sous clips)
		 */
		public static function desactivateTabIndex(clip:Object) {	
			
			if (clip is InteractiveObject) {
					clip.tabEnabled = false;
			}
			try {
				clip.tabChildren = false;
			}catch (e) {
				
			}
			
			if (clip is DisplayObjectContainer) {
				var nb:int = clip.numChildren;
				
				for (var i:int = 0; i < nb; i++)
				{
					var obj:DisplayObject = clip.getChildAt(i);
					desactivateTabIndex(obj);
				}
			}
		}
		
		public static function setColor(displayObject:DisplayObject, color:Number):void
		{
			var newColorTransform:ColorTransform = displayObject.transform.colorTransform;
			newColorTransform.color = color;

			displayObject.transform.colorTransform = newColorTransform;
		}
	}
}
